<?php

/**
 * 通过手牌判断某个牌是否能吃，能比；能正常吃则返回吃的数组‘否则则返回一个空的数组
 * Class PHZ_Chi_Bi_Pai
 */
class PHZ_Chi_Bi_Pai
{

    /**
     * 吃牌重要环节：吃牌的判断，同时进行比牌信息判断
     * @param $card           吃的牌号
     * @param $shoupai        手牌信息
     * @param $room_info      房间ROOM信息
     * @return array|bool     返回能被吃的完整的牌面数组信息
     */
    public static function __chi_pai_bi_pai_chk( $card , $shoupai , $room_info ){
        return self::__chiBI( $card , $shoupai , self::__chi_pai_1_5_10( $room_info ) );
    }

    /**
     * 是否打1.5.10,不打则不能算吃类型
     * @param $room_info
     */
    public static function __chi_pai_1_5_10( $room_info ){
        $mttype = $room_info['room_mtype'];
        if( strstr( $mttype  , "2" ) == true ){
            return true;
        }
        return false;
    }


    public static function __issetDoubleCard_three( $hand_array , $card_1 , $card_2 , $card_3 ){
        $find = 0;
        foreach ( $hand_array as $key => $value ){
            if( $value == $card_1 ){unset( $hand_array[$key]);$find ++ ;break;}
        }
        foreach ( $hand_array as $key => $value ){
            if( $value == $card_2 ){unset( $hand_array[$key]);$find ++ ;break;}
        }
        foreach ( $hand_array as $key => $value ){
            if( $value == $card_3 ){unset( $hand_array[$key]);$find ++ ;break;}
        }
        if( $find == 3 ){
            return true;
        }
        return false;
    }

    public static function __issetDoubleCard( $hand_array , $card_1 , $card_2 ){
        $find = 0;
        foreach ( $hand_array as $key => $value ){
            if( $value == $card_1 ){unset( $hand_array[$key]);$find ++ ;break;}
        }
        foreach ( $hand_array as $key => $value ){
            if( $value == $card_2 ){unset( $hand_array[$key]);$find ++ ;break;}
        }
        if( $find == 2 ){
            return true;
        }
        return false;
    }

    public static function __del_card_three( $hand_array , $card_1 , $card_2 , $card_3 ){
        foreach ( $hand_array as $key => $value ){
            if( $value == $card_1 ){unset( $hand_array[$key] );break;}
        }
        foreach ( $hand_array as $key => $value ){
            if( $value == $card_2 ){unset( $hand_array[$key] );break;}
        }
        foreach ( $hand_array as $key => $value ){
            if( $value == $card_3 ){unset( $hand_array[$key] );break;}
        }
        return array_values( $hand_array );
    }

    public static function __del_card( $hand_array , $card_1 , $card_2 ){
        foreach ( $hand_array as $key => $value ){
            if( $value == $card_1 ){unset( $hand_array[$key] );break;}
        }
        foreach ( $hand_array as $key => $value ){
            if( $value == $card_2 ){unset( $hand_array[$key] );break;}
        }
        return array_values( $hand_array );
    }

    /**
     * 写死判断每一张牌全部可能存在的吃的匹配组合
     * @param $card_number
     * @param $is_1510
     * @return array
     */
    public static function get_canChifind( $card_number , $is_1510 ){
        switch( $card_number ){
            case 1:
                if( $is_1510 == true ){
                    $sp_find = array(array(1, 11), array(11, 11), array(2, 3), array(5, 10));
                }else {
                    $sp_find = array(array(1, 11), array(11, 11), array(2, 3));
                }
                break;
            case 2:
                $sp_find = array( array(2,12),array(12,12),array(3,4),array(1,3),array(7,10) );
                break;
            case 3:
                $sp_find = array( array(3,13),array(13,13),array(1,2),array(2,4),array(4,5) );
                break;
            case 4:
                $sp_find = array( array(4,14),array(14,14),array(2,3),array(3,5),array(5,6) );
                break;
            case 5:
                if( $is_1510 == true ){
                    $sp_find = array(array(5, 15), array(15, 15), array(3, 4), array(4, 6), array(6, 7), array(1, 10));
                }else {
                    $sp_find = array(array(5, 15), array(15, 15), array(3, 4), array(4, 6), array(6, 7));
                }
                break;
            case 6:
                $sp_find = array( array(6,16),array(16,16),array(4,5),array(5,7),array(7,8) );
                break;
            case 7:
                $sp_find = array( array(7,17),array(17,17),array(5,6),array(6,8),array(8,9),array(2,10) );
                break;
            case 8:
                $sp_find = array( array(8,18),array(18,18),array(6,7),array(7,9),array(9,10) );
                break;
            case 9:
                $sp_find = array( array(9,19),array(19,19),array(7,8),array(8,10) );
                break;
            case 10:
                if( $is_1510 == true ) {
                    $sp_find = array(array(10, 20), array(20, 20), array(8, 9), array(1, 5), array(2, 7));
                }else{
                    $sp_find = array(array(10, 20), array(20, 20), array(8, 9),array(2, 7));
                }
                break;
            case 11:
                if( $is_1510 == true ) {
                    $sp_find = array(array(1, 11), array(1, 1), array(12, 13), array(15, 20));
                }else{
                    $sp_find = array(array(1, 11), array(1, 1), array(12, 13));
                }
                break;
            case 12:
                $sp_find = array( array(2,12),array(2,2),array(13,14),array(11,13),array(17,20) );
                break;
            case 13:
                $sp_find = array( array(3,13),array(3,3),array(11,12),array(12,14),array(14,15) );
                break;
            case 14:
                $sp_find = array( array(4,14),array(4,4),array(12,13),array(13,15),array(15,16) );
                break;
            case 15:
                if( $is_1510 == true ) {
                    $sp_find = array(array(5, 15), array(5, 5), array(13, 14), array(14, 16), array(16, 17), array(11, 20));
                }else{
                    $sp_find = array(array(5, 15), array(5, 5), array(13, 14), array(14, 16), array(16, 17));
                }
                break;
            case 16:
                $sp_find = array( array(6,16),array(6,6),array(14,15),array(15,17),array(17,18) );
                break;
            case 17:
                $sp_find = array( array(7,17),array(7,7),array(15,16),array(16,18),array(18,19),array(12,20) );
                break;
            case 18:
                $sp_find = array( array(8,18),array(8,8),array(16,17),array(17,19),array(19,20) );
                break;
            case 19:
                $sp_find = array( array(9,19),array(9,9),array(17,18),array(18,20) );
                break;
            case 20:
                if( $is_1510 == true ) {
                    $sp_find = array(array(10, 20), array(10, 10), array(18, 19), array(11, 15), array(12, 17));
                }else{
                    $sp_find = array(array(10, 20), array(10, 10), array(18, 19), array(12, 17));
                }
                break;
        }
        return $sp_find;
    }

    /**
     * 吃牌+比牌算法
     * @param $card
     * @param $hand_sp
     * @param $is_1510  是否打1510
     * @return array|bool
     */
    public static function __chiBI( $card , $hand_sp , $is_1510 ){
        $hand_array    = explode( "," , $hand_sp );
        $ha_card_count = array_count_values( $hand_array );
        #.第一步:如果手中有3个或者4个吃的牌，则不允许执行
        if( isset( $ha_card_count[$card] ) && $ha_card_count[$card] >= 3 ){
            return false;
        }
        #.第二步:去除牌内所有的三张跟四张，避免被混淆到吃的序列里面
        foreach ( $ha_card_count as $key => $value ){
            if( $value <= 2 ){ continue; }
            foreach ( $hand_array as $key_1 => $value_1 ){if( $key == $value_1 ){unset( $hand_array[$key_1] );}}//小于等于2个不用管他
        }
        #.第三步:查询出一个牌的所有吃的可能性组合
        $combin = self::get_canChifind( $card , $is_1510 );
        #.第四步:查询每一个组合；手中是否有这个牌，没有这个牌就把这个组合删掉，并重置组合索引
        foreach ( $combin as $key => $value ){
            if( self::__issetDoubleCard( $hand_array , $value[0] , $value[1] ) == false ){
                unset( $combin[$key] );//如果有不存在的任何一个牌，就要删除这个组合
            }
        }
        $card_count = isset( $ha_card_count[$card] ) ? ($ha_card_count[$card]+1) : 1;//需要被消耗的牌数量
        $eat        = array();
        #.第五步:遍历每一种组合;在里面进行更深层次的组合查询；- 这里其实有多少种组合,那么展示在前台的layer第一层就有多少种
        foreach ( $combin as $key => $value ){
            //每次重置吃组合
            $combin_array    = $combin;
            //重置吃牌组合数组跟牌数据
            $eatType         = array();
            $pai_array       =  $hand_array;
            //添加并删除第一吃的吃法跟牌
            $pai_array       = self::__del_card( $pai_array , $value[0] , $value[1] );
            $eatType['chi']  = $value[0] . "_" . $value[1];
            $eatType['ccc']  = self::__getStringINcard( $eatType['chi'] . "_" . $card , $card );
            //继续遍历该牌的所有吃法,如果手牌中还有能匹配的吃法牌；则继续遍历 - 到了第二层开始；就要匹配三个牌；因为第一层肯定是吃掉一个牌；第二层的吃就是手中的牌了
            $layer_2         = 0;
            foreach ( $combin_array as $key_1 => $value_1 ){
                //重置一次剩余的第二吃要比较的牌
                $er_pai_array = $pai_array;
                if( self::__issetDoubleCard_three( $er_pai_array , $value_1[0] , $value_1[1] , $card ) == true ){
                    //添加并删除第二吃的吃法跟牌
                    $eatType[$layer_2] = array();
                    $eatType[$layer_2]['chi'] = $value_1[0] . "_" . $value_1[1];
                    $eatType[$layer_2]['ccc'] = self::__getStringINcard( $eatType[$layer_2]['chi'] . "_" . $card , $card );
                    $er_pai_array  = self::__del_card_three( $er_pai_array , $value_1[0] , $value_1[1] , $card );
                    //继续遍历该牌的所有吃法
                    $layer_3 = 0;
                    foreach ( $combin_array as $key_3 => $value_3 ){
                        //重置一次剩余的第三吃要比的牌
                        $san_pai_array = $er_pai_array;
                        if( self::__issetDoubleCard_three( $san_pai_array , $value_3[0] , $value_3[1] , $card ) == true ){
                            $eatType[$layer_2][$layer_3] = array();
                            $eatType[$layer_2][$layer_3]['chi'] = $value_3[0] . "_" . $value_3[1];
                            $eatType[$layer_2][$layer_3]['ccc'] = self::__getStringINcard( $eatType[$layer_2][$layer_3]['chi'] . "_" . $card , $card );
                            $layer_3++;
                        }
                    }
                    $layer_2++;
                }
            }
            //遍历该吃法;分别查询1，2，3级；如果消耗牌数不对等；则不能吃
            $eatType_Esx = self::__callEsx( $eatType , $card_count );
            if( $eatType_Esx !== false ) {
                array_push( $eat, $eatType_Esx);
            }
        }
        if( count( $eat ) <= 0 ){
            return false;
        }
        return $eat;
    }

    public static function __callEsx( $eatType , $card_count){
        $this_xiaohao_count = 0;
        foreach ( $eatType as $key => $value ){
            if( ! isset( $eatType[0] ) ){//如果没有第二层了，那么第一层的ccc就是要消耗掉的值
                $this_xiaohao_count = $eatType['ccc'];//只记录第一次的消耗
                if( $eatType['ccc'] != $card_count ){unset( $eatType );return false;break;}//如果没有第二层，且数量还不满足，那么这个是要直接被删除并返回false的；
            }else if( is_int($key) ){
                foreach ( $value as $key_1 => $value_1 ){
                    if( ! isset( $value[0] ) ){//如果没有第三层了；那么就是第一层加上这一层的CCC；如果总数不等于，那么就要删除本第二层
                        $this_xiaohao_count = ($eatType['ccc'] + $value['ccc']);
                        if( ($eatType['ccc'] + $value['ccc']) != $card_count ){unset( $eatType[$key] );break;}//如果只有第二层且没有第三层；数量又不满足的情况下,则删除这个第二层
                    }else if( is_int($key_1) ){
                        foreach ( $value_1 as $key_2 => $value_2 ){
                            $this_xiaohao_count = ($eatType['ccc'] + $value['ccc'] + $value_1['ccc']);
                            if( ($eatType['ccc'] + $value['ccc'] + $value_1['ccc']) != $card_count ){
                                unset( $eatType[$key][$key_1] );break;
                            }
                        }
                    }
                }
            }
        }
        if( $this_xiaohao_count < $card_count ){
            return false;
        }
        return $eatType;
    }

    public static function __getStringINcard( $chi , $card ){
        $find = 0;
        $chi_array = explode("_",$chi);
        foreach ( $chi_array as $value ){
            if( $value == $card ){
                $find++;
            }
        }
        return $find;
    }

}